package com.zhangx.study.demo.forkjoin.controller;

import com.alibaba.fastjson.JSONObject;
import com.zhangx.study.demo.forkjoin.constant.RequestQueue;
import com.zhangx.study.demo.forkjoin.dto.OrderRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ClassName PayController
 * @Description 支付
 * @Author zhangx
 * @Date 2020/6/17 15:52
 **/
@Slf4j
@RestController
@RequestMapping("pay")
public class PayController {

    @Autowired
    private RestTemplate restTemplate;

    private static final int MAX_THREADS = 10000;

    private CountDownLatch countDownLatch = new CountDownLatch(MAX_THREADS);

    private static AtomicInteger count = new AtomicInteger(0);

    @GetMapping("one")
    public void payOneOrder(){
        log.info("--start--");
        for (int i = 0; i < MAX_THREADS; i++) {
            Thread t = new Thread(()->{
                countDownLatch.countDown();
                try {
                    countDownLatch.await();
                    count.incrementAndGet();
                    JSONObject result = callRemoteServiceOne(String.valueOf(count));
                    log.info(result.toJSONString());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            t.start();
        }
    }

    private JSONObject callRemoteServiceOne(String orderNo){
        JSONObject result = null;
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        Map<String, String> map = new HashMap<String, String>();
        map.put("orderNo", orderNo);
        map.put("id", UUID.randomUUID().toString());
        HttpEntity<Map> request = new HttpEntity<Map>(map, headers);

        ResponseEntity<JSONObject> wcsResp = restTemplate.postForEntity("http://localhost:6060/remote/order/confirm", request, JSONObject.class);
        if (wcsResp.getStatusCodeValue() != 200) {
            log.error("调用接口失败！");
        } else {
            result = wcsResp.getBody();
        }
        return result;
    }


    @GetMapping("mul")
    public void payMulOrder(){
        log.info("--start--");
        for (int i = 0; i < MAX_THREADS; i++) {
            Thread t = new Thread(()->{
                countDownLatch.countDown();
                try {
                    countDownLatch.await();
                    count.incrementAndGet();
                    JSONObject result = callRemoteServiceMul(String.valueOf(count));
                    log.info(result.toJSONString());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            });
            t.start();
        }
    }

    private JSONObject callRemoteServiceMul(String orderNo) throws ExecutionException, InterruptedException {
        CompletableFuture<JSONObject> future = new CompletableFuture<>();
        OrderRequest orderRequest = new OrderRequest();
        orderRequest.setId(UUID.randomUUID().toString());
        orderRequest.setOrderNo(orderNo);
        orderRequest.setFuture(future);
        RequestQueue.queue.add(orderRequest);
        return future.get();
    }
}
